package FanXingT;

import entity.Person;

import java.util.*;

/**
* @author jie
* @version 创建时间：2018年9月7日 下午3:52:41
* 类说明 累的继承 instance 能区分是否当前类对象
 *
 * https://www.jianshu.com/p/86cf908afcb6

 * Java语言引入泛型的好处是安全简单。
 *
 * 泛型的使用方式
 *
 * 泛型有三种使用方式，分别为：泛型类、泛型接口、泛型方法
 * @see ObjectTool
 *
 *
 *  PECS 法则
 *  *
 *  * 如果要从集合中读取类型T的数据，并且不能写入，可以使用 ? extends 通配符；(Producer Extends)
 *  *
 *  * 如果要从集合中写入类型T的数据，并且不需要读取，可以使用 ? super 通配符；(Consumer Super)
 *  *
 *  * 如果既要存又要取，那么就不要使用任何通配符。
 *
*/
public class extendInstanceOf {

	 public static void main(String[] args) {

	 	collectionCopyDemo();
		Life pLife = new Persion();

		System.out.println(pLife instanceof Persion);

		System.out.println(pLife instanceof Asion);

		System.err.println(pLife instanceof Plant);

		 // Number "extends" Number (in this context)
		 List<? extends Number> foo6 = new ArrayList< Number>();
//		 Integer extends Number
		 List<? extends Number> foo7 = new ArrayList< Integer>();
//		 Double extends Number
		 List<? extends Number> foo8 = new ArrayList< Double>();
//		 Number number = foo6.get(0);
		 Integer mInteger = 123;
//		 pecs
//		 foo6.add(1);
//		 foo6.add(0,mInteger);//报错不能插入!!!!!





		 Map<String,? extends Number> map= new HashMap<>();
//		 map.put("1",mInteger);//报错不能插入!!!!!
		 Number a = map.get("a");

		 Map<String,Class<? extends Number>> map2= new HashMap<>();
		 map2.put("1",Number.class);//todo 因为 插入的都是 Class 对象，所以ok ? . extends 呢？类型参数不校验？
		 map2.put("2",Integer.class);
//		 map.put("3", Person.class);//编译检查报错，不兼容类型。
		 String name = map2.get("1").getName();
		 System.out.println("set  Class<? extends Number> .get():"+name);



		 // @link{FanXing_PESC.java}
// Integer is a "superclass" of Integer (in this context)
			List<? super Integer> foo3 = new ArrayList<Integer>();
			// Number is a superclass of Integer
		 List<? super Integer> foo4 = new ArrayList<Number>();
		 // Object is a superclass of Integer
		 List<? super Integer> foo5 = new ArrayList<Object>();

		 Object object = foo3.get(0);//只能 get 出来 object

	 }


	//1.ArrayList声明时默认的元素个数是0，只有进行add（），remove（）操作时size（）的大小才有相应的变化。
	//2.进行集合复制时，一要声明目的集合的元素的个数，并且要等于或者大于源集合的元素的个数。
	//3.如果不声明或者小于源集合的元素个数，这样就会报错，报下标界的异常（java.lang.IndexOutOfBoundsException）。
	//原文链接：https://blog.csdn.net/weixin_43610698/article/details/95861362
	private static void collectionCopyDemo() {
		List<Number> origin = new ArrayList<>();
		origin.add(1);
		origin.add(2);
		origin.add(3);
//		List<Number> dest = new ArrayList<>(3);//todo java.lang.IndexOutOfBoundsException

		//method 1
//		List<Number> dest = Arrays.asList(new Number[origin.size()]);

		//method 2
		List<Number> dest = new ArrayList<>(3);
		Collections.addAll(dest,new Number[origin.size()]);

		Collections.copy(dest,origin);
		System.out.println("Collections.copy .dest.size:"+dest.size());
		System.out.println("dest.get(0):"+dest.get(0));
	}

}

class Life{
	public int age;
}

class Persion extends Life{
	public String name;
}

class Asion extends Persion{
	public String skinColor = "yellow";
}

class Plant extends Life {
	public boolean vegetable;
 }


